Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Rendered β€’ View raw β€’ Download

desktop/README.md 13865e7c8b7f9a47cd3b572bd44d8ec355b2d3a9 (13865e7c) Text, 8.60 KB

T383838:desktop β€” Meshtastic Desktop

A Compose Desktop application target β€” the first full non-Android target for the shared KMP module graph. This module serves as:

1. First multi-target milestone β€” Proves the KMP architecture supports real application targets beyond Android.
2. Build smoke-test β€” Validates that all T383838core:* KMP modules compile and link on a JVM Desktop target.
3. Shared navigation proof β€” Uses the same Navigation 3 routes from T383838core:navigation and the same T383838NavDisplay + T383838entryProvider pattern as the Android app, proving the shared backstack architecture works cross-target.
4. Desktop app scaffold β€” A working Compose Desktop application with a T383838NavigationRail for top-level destinations and placeholder screens for each feature.

Quick Start

T282828
T8b949e# Run the desktop app
./gradlew :desktop:run

T8b949e# Run tests
./gradlew :desktop:test

T8b949e# Package native distribution (DMG/MSI/DEB) β€” debug (no ProGuard)
./gradlew :desktop:packageDistributionForCurrentOS

T8b949e# Package native distribution (DMG/MSI/DEB) β€” release (ProGuard minified)
./gradlew :desktop:packageReleaseDistributionForCurrentOS


ProGuard / Minification

Release builds use ProGuard for tree-shaking (unused code removal), significantly reducing distribution size. Obfuscation is disabled since the project is open-source. Rules are aligned with the Android R8 rules in T383838app/proguard-rules.pro β€” both targets share the same anti-class-merging philosophy.

Configuration:
β€’ T383838build.gradle.kts β€” T383838buildTypes.release.proguard block enables ProGuard with T383838optimize.set(true) and T383838obfuscate.set(false).
β€’ T383838proguard-rules.pro β€” Keep-rules for reflection/JNI-sensitive dependencies (Koin, kotlinx-serialization, Wire protobuf, Room KMP T383838androidx.room3, Ktor, Kable BLE, Coil, SQLite JNI, Compose Multiplatform resources) and an anti-merge rule for Compose animation classes.

Key rules:
β€’ Compose animation anti-merge (T383838-keep class androidx.compose.animation.** { *; }) β€” Prevents ProGuard's optimizer from incorrectly tree-shaking or merging animation class hierarchies (e.g. T383838EnterTransition/T383838ExitTransition into T383838*Impl), which causes animations to silently snap. Same rule as Android.
β€’ Room KMP β€” Uses T383838androidx.room3 package path (Room KMP 3.x).

Troubleshooting ProGuard issues:
β€’ If the release build crashes at runtime with T383838ClassNotFoundException or T383838NoSuchMethodError, a library is loading classes via reflection that ProGuard stripped. Add a T383838-keep rule in T383838proguard-rules.pro and the corresponding rule in T383838app/proguard-rules.pro to keep both targets aligned.
β€’ To debug which classes ProGuard removes, temporarily add T383838-printusage proguard-usage.txt to the rules file and inspect the output in T383838desktop/proguard-usage.txt.
β€’ To see the full mapping of optimizations applied, add T383838-printseeds proguard-seeds.txt.
β€’ Run T383838./gradlew :desktop:runRelease for a quick smoke-test of the minified app before packaging.

Architecture

The module depends on the JVM variants of KMP modules:

β€’ T383838core:common, T383838core:model, T383838core:di, T383838core:navigation, T383838core:repository
β€’ T383838core:domain, T383838core:data, T383838core:database, T383838core:datastore, T383838core:prefs
β€’ T383838core:network, T383838core:resources, T383838core:ui

Navigation: Uses JetBrains multiplatform forks of Navigation 3 (T383838org.jetbrains.androidx.navigation3:navigation3-ui) and Lifecycle (T383838org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose, T383838lifecycle-runtime-compose). A unified T383838SavedStateConfiguration with polymorphic T383838SerializersModule is provided centrally by T383838core:navigation for non-Android NavKey serialization. Desktop utilizes the exact same navigation graph wiring (T383838settingsGraph, T383838nodesGraph, T383838contactsGraph, T383838connectionsGraph) directly from the T383838commonMain of their respective feature modules, maintaining full UI parity.

Coroutines: Requires T383838kotlinx-coroutines-swing for T383838Dispatchers.Main on JVM/Desktop. Without it, any code using T383838lifecycle.coroutineScope or T383838Dispatchers.Main (e.g., T383838NodeRepositoryImpl, T383838RadioConfigRepositoryImpl) will crash at runtime.

DI: A Koin DI graph is bootstrapped in T383838Main.kt with platform-specific implementations injected.

UI: JetBrains Compose for Desktop with Material 3 theming. Desktop acts as a thin host shell, delegating almost entirely to fully shared KMP UI modules. Includes native OS notifications (macOS T383838UNUserNotificationCenter, Linux libnotify, Windows toast) and a monochrome SVG tray icon for a native look and feel.

Notifications: Implements the common T383838NotificationManager interface via T383838DesktopNotificationManager. Repository-level notifications (messages, node events, alerts) are collected in T383838Main.kt and forwarded to platform-native senders; the app falls back to Compose T383838TrayState notifications only if native delivery fails. macOS requires a consistent T383838bundleID (configured in T383838build.gradle.kts) for proper app attribution.

Localization: Desktop exposes a language picker, persisting the selected BCP-47 tag in T383838UiPreferencesDataSource.locale. T383838Main.kt applies the override to the JVM default T383838Locale and uses a T383838staticCompositionLocalOf-backed recomposition trigger so Compose Multiplatform T383838stringResource() calls update immediately without recreating the Navigation 3 backstack.

Key Files

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ File β”‚ Purpose β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ T383838Main.kt β”‚ App entry point β€” Koin bootstrap, Compose Des… β”‚
β”‚ T383838DemoScenario.kt β”‚ Offline demo data for testing without a conne… β”‚
β”‚ T383838ui/DesktopMainScreen.kt β”‚ Navigation 3 shell β€” T383838NavigationRail + T383838NavDisp… β”‚
β”‚ T383838navigation/DesktopNavigation.kt β”‚ Nav graph entry registrations for all top-lev… β”‚
β”‚ T383838radio/DesktopRadioTransportFactory.kt β”‚ Provides TCP, Serial/USB, and BLE transports β”‚
β”‚ T383838notification/DesktopMeshServiceNotifications.kt β”‚ Real implementation of notification triggers … β”‚
β”‚ T383838DesktopNotificationManager.kt β”‚ Bridge between repository notifications and C… β”‚
β”‚ T383838radio/DesktopMeshServiceController.kt β”‚ Mesh service lifecycle β€” orchestrates T383838want_co… β”‚
β”‚ T383838radio/DesktopMessageQueue.kt β”‚ Message queue for outbound mesh packets β”‚
β”‚ T383838di/DesktopKoinModule.kt β”‚ Koin module with stub implementations β”‚
β”‚ T383838di/DesktopPlatformModule.kt β”‚ Platform-specific Koin bindings β”‚
β”‚ T383838stub/NoopStubs.kt β”‚ No-op implementations for all repository inte… β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

What This Validates

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Module β”‚ What's Tested β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ T383838core:common β”‚ T383838Base64Factory, T383838NumberFormatter, T383838UrlUtils, T383838DateFormatter, T383838CommonUri β”‚
β”‚ T383838core:model β”‚ T383838DeviceVersion, T383838Capabilities, T383838SfppHasher, T383838platformRandomBytes, T383838getShortDateTime, T383838C… β”‚
β”‚ T383838core:ui β”‚ Shared Compose components compile and render on Desktop β”‚
β”‚ Build graph β”‚ All core modules compile and link without Android SDK β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Roadmap

β€’ [x] Implement real navigation with shared T383838core:navigation routes (Navigation 3 shell)
β€’ [x] Adopt JetBrains multiplatform forks for lifecycle and navigation3
β€’ [x] Implement native macOS/Desktop notification support with T383838TrayState and system tray
β€’ [x] Wire T383838feature:settings composables into the nav graph (first real feature β€” ~30 screens)
β€’ [x] Wire T383838feature:node composables into the nav graph (node list with shared ViewModel + NodeItem)
β€’ [x] Wire T383838feature:messaging composables into the nav graph (contacts list with shared ViewModel)
β€’ [x] Add JetBrains Material 3 Adaptive T383838ListDetailPaneScaffold to node and messaging screens
β€’ [x] Implement TCP transport (T383838DesktopRadioTransportFactory) with auto-reconnect and backoff retry
β€’ [x] Implement mesh service controller (T383838DesktopMeshServiceController) with full T383838want_config handshake
β€’ [x] Create connections screen using shared T383838feature:connections with dynamic transport detection
β€’ [x] Replace 5 placeholder config screens with real desktop implementations (Device, Position, Network, Security, ExtNotification)
β€’ [x] Add desktop language picker backed by shared T383838UiPreferencesDataSource.locale with live translation updates
β€’ [x] Wire remaining T383838feature:* composables (map) into the nav graph
β€’ [x] Move remaining node detail and message composables from T383838androidMain to T383838commonMain
β€’ [x] Add serial/USB transport for direct radio connection on Desktop
β€’ [x] Add BLE transport (via Kable) for direct radio connection on Desktop
β€’ [x] Add MQTT transport for cloud-connected operation
β€’ [x] Package as native distributions (DMG, MSI, DEB) via CI release pipeline

Served by rngit 1.5.0 - Generated in 0.05s